package com.orzxlee.InterviewQuestions.Java_SE_Advanced;

import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

public class Demo {

    public static void main(String[] args) {


        //1.反射 获取字节码三种方法
        //1.Class.forName(className) 2.类名.class 3.this.getClass()
        //fun1();

        //2.Java 中的23种设计模式&回收机制
        /*
            创建型模式，共五种：工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
            结构型模式，共七种：适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
            行为型模式，共十一种：策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模
                              式、状态模式、访问者模式、中介者模式、解释器模式

         */

        //3. GC回收器  Java 中引用类型都有哪些？（重要）
        //Java 中对象的引用分为四种级别，这四种级别由高到低依次为：强引用、软引用、弱引用和虚引用。
        //fun3();

        //4. heap(堆) 和 stack(栈) 有什么区别?
        //fun4();

        //5.对于 Java 的 GC 哪些内存需要回收,什么时候回收?
        /*
            它主要包括 5 大部分:程序计数器(Program CounterRegister)、
                             虚拟机栈(VM Stack)、
                             本地方法栈(Native Method Stack)、
                             方法区(Method Area)、
                             堆(Heap)

            1.对于 Java 的 GC 哪些内存需要回收?
                程序计数器、虚拟机栈、本地方法栈是每个线程私有的内存空间，随线程而生，随线程而亡

                Method area(方法区)和heap(堆) 程序运行才会开辟内存空间,GC 主要关注的是这部分内存
            2.Java 的 GC 什么时候回收垃圾
                对于堆中的对象，主要用可达性分析判断一个对象是否还存在引用，如果该对象没有任何引用就应该被回收。
                根据我们实际对引用的不同需求，又分成了 4 中引用(强,软,弱,虚)，每种引用的回收机制也是不同的。
                对于方法区中的常量和类，当一个常量没有任何对象引用它，它就可以被回收了。
                对于类，如果可以判定它为无用类，就可以被回收了

         */


    }

    private static void fun4() {
        //stack(栈):由系统自动分配 ,声明在函数中一个局部变量 int b; 系统自动在栈中为 b 开辟空间
        //heap(堆):需要程序员自己申请，并指明大小

        //stack(栈)基本数据类型的变量，一个对象的引用 ,保存JVM 中的栈空间
        //heap(堆)new 关键字和构造器创建的对象,放在堆空间
        //method area(方法区) 字面量（literal）如直接书写的 100、"hello"和常量都是放在常量池中,常量池是方法区的一部分
        String str = new String("hello");
        //上面的语句中变量 str 放在栈上，用 new 创建出来的字符串对象放在堆上，而"hello"这个字面量是放在方法区的。
    }

    private static void fun3() {
        String abc=new String("abc"); //1   强引用
        SoftReference<String> softRef=new SoftReference<String>(abc); //2  强引用
        WeakReference<String> weakRef = new WeakReference<String>(abc); //3 强引用
        abc=null; //4  软引用
        softRef.clear();//5 弱引用

        /*
        第一行在 heap 堆中创建内容为“abc”的对象，并建立 abc 到该对象的强引用，该对象是强可及的。
        第二行和第三行分别建立对 heap 中对象的软引用和弱引用，此时 heap 中的 abc 对象已经有 3 个引用，显然此时 abc 对象仍是强可及的。
        第四行之后 heap 中对象不再是强可及的，变成软可及的。
        第五行执行之后变成弱可及的。

        软引用:内存空间足够，垃圾回收器不回收它，内存空间不足，回收这些对象的内存,软引用可用来实现内存敏感的高速缓存
        弱引用:因为只要该对象被 gc 扫描到了随时都会把它干掉
        虚引用:虚引用主要用来跟踪对象被垃圾回收的活动

         */
    }

    private static void fun1() {
    /*
        1.JDK动态代理是实现 JDK 里的 InvocationHandler 接口的 invoke 方法，但注意的是代理的是接口，
            也就是你的业务类必须要实现接口，通过 Proxy 里的 newProxyInstance 得到代理对象
        2.CGLIB，代理的是类，不需要业务类继承接口，通过派生的子类来实现代理

        AOP 编程就是基于动态代理实现的，比如著名的 Spring 框架、Hibernate 框架等等都是动态代理的使用例子。

     */
    }


}


